package com.mr.qa.action;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;
import org.hibernate.Transaction;

import com.mr.qa.UserSession;
import com.mr.qa.UserSessionUtil;
import com.mr.qa.bo.SharedFileCategory;
import com.mr.qa.dao.impl.SharedFileCategoryDAO;
import com.mr.qa.dao.impl.SharedFileDAO;
import com.mr.qa.exception.QaException;
import com.mr.qa.form.SharedFileCategoryForm;
import com.mr.qa.util.HibernateSessionFactory;

public class SharedFileCategoryAction extends DispatchAction 
{
    private static final Log log = LogFactory.getLog(SharedFileCategoryAction.class);

    private ActionForward checkIfUserIsAdmin(ActionMapping mapping,HttpServletRequest request,ActionMessages errors)
    {
        UserSession us = UserSessionUtil.getUserSession(request);
        ActionForward af = null;
        if(us == null)
        {
            errors.add("relogin", new ActionMessage("login.required"));
            saveErrors(request, errors);
            af = mapping.findForward("relogin"); 
        }
        else
        {
            if(!us.getType().equals("1"))
            {
                errors.add("noright", new ActionMessage("user.noright"));
                saveErrors(request, errors);
                af = mapping.findForward("relogin");
            }else if(!us.isAdminPasswordInput()){
            	StringBuffer uri = new StringBuffer(request.getRequestURI() + "?");
            	Enumeration paramNames = request.getParameterNames();
            	int i = 0;
            	while(paramNames.hasMoreElements()){
            		if(i != 0){
            			uri.append("&");
            		}
            		String name = (String)paramNames.nextElement();
            		uri.append(name + "=");
            		uri.append(request.getParameter(name));
            		i++;
            	}
            	
            	request.setAttribute("preURI",uri.toString());
            	af = mapping.findForward("adminPass");
            }
        }
        return af;
    }
    
    //add a category for admin
    public ActionForward add(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        ActionForward af = null;
        ActionMessages errors = new ActionMessages();        
        af = checkIfUserIsAdmin(mapping,request,errors);
        if(af != null)return af;
    
        SharedFileCategoryForm categoryForm = (SharedFileCategoryForm)form;
        Integer parentId = categoryForm.getParentId();
        add(categoryForm);
        String path = mapping.findForward(getStrutsMappingParamterValue(mapping,request)).getPath();
        path = path.replace("?parentId",""+parentId);
        af = new ActionForward(path);
        af.setRedirect(true);
        return af;
    }

    //preadd a category for admin
    public ActionForward preadd(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        ActionForward af = null;
        ActionMessages errors = new ActionMessages();        
        af = checkIfUserIsAdmin(mapping,request,errors);
        if(af != null)return af;
        af = mapping.findForward(getStrutsMappingParamterValue(mapping,request));
        return af;
    }

    //modify a category for admin
    public ActionForward modify(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        ActionForward af = null;
        ActionMessages errors = new ActionMessages();        
        af = checkIfUserIsAdmin(mapping,request,errors);
        if(af != null)return af;
    
        SharedFileCategoryForm categoryForm = (SharedFileCategoryForm)form;
        modify(categoryForm);
        af = new ActionForward(mapping.findForward("modify").getPath());
        af.setRedirect(true);
        return af;
        
    }

    //view a category for admin
    public ActionForward view(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        ActionForward af = null;
        ActionMessages errors = new ActionMessages();        
        af = checkIfUserIsAdmin(mapping,request,errors);
        if(af != null)return af;
    
        SharedFileCategoryForm categoryForm = (SharedFileCategoryForm)form;
        Integer id = categoryForm.getId();
        int page = categoryForm.getPage();
        int pageSize = categoryForm.getPageSize();
        if(page == 0)page = 1;
        if(pageSize == 0)pageSize = 1;
        if(id != null && id.intValue() > 0)
        {
            request.setAttribute("sfc",get(id));
            request.setAttribute("resultSize",this.countSharedFile(id));
            request.setAttribute("sfs",this.list(page,pageSize,id));
            //
        }
        else
        {
            Collection list = null;
            list = listAll();
            request.setAttribute("sfclist",list);
        }
        af = new ActionForward(mapping.findForward("view").getPath());
        af.setRedirect(true);
        return af;
    }

    //list all categories under a parent category
    public ActionForward list(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        ActionForward af = null;
        ActionMessages errors = new ActionMessages();        
        af = checkIfUserIsAdmin(mapping,request,errors);
        if(af != null)return af;
    
        SharedFileCategoryForm categoryForm = (SharedFileCategoryForm)form;
        Integer id = categoryForm.getId();
        if(id == null)
        {
            Collection list = null;            
            list = listAll();
            request.setAttribute("sfclist",list);
        }
        else
        {
            SharedFileCategory sfc = get(id);
            request.setAttribute("sfc",sfc);
            log.info("list size="+sfc.getMrIaskSharedFileCategories().size());
        }
        af = new ActionForward(mapping.findForward("list").getPath());
        af.setRedirect(true);
        return af;
    }

    //delete a category for admin
    public ActionForward delete(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        ActionForward af = null;
        ActionMessages errors = new ActionMessages();        
        af = checkIfUserIsAdmin(mapping,request,errors);
        if(af != null)return af;
        SharedFileCategoryForm categoryForm = (SharedFileCategoryForm)form;
        delete(categoryForm.getId());
        af = new ActionForward(mapping.findForward("delete").getPath());
        af.setRedirect(true);
        return af;
    }


    private String getStrutsMappingParamterValue(ActionMapping mapping,HttpServletRequest request)
    {
        return request.getParameter(mapping.getParameter());
    }



//====================
    /*
    public ActionForward doAction(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        UserSession session = UserSessionUtil.getUserSession(request);
        String action = "";
        SharedFileCategoryForm categoryForm = (SharedFileCategoryForm)form;
        Integer id = categoryForm.getId();
        ActionForward af = null;
        if("add".equals(action))
        {
            add(categoryForm);
            af = new ActionForward(mapping.findForward(action).getPath());
            af.setRedirect(true);
        }
        else if("delete".equals(action))
        {
            delete(id);
            af = new ActionForward(mapping.findForward(action).getPath());
            af.setRedirect(true);
        }
        else if("modify".equals(action))
        {
            modify(categoryForm);
            af = new ActionForward(mapping.findForward(action).getPath());
            af.setRedirect(true);
        }
        else if("view".equals(action))
        {
            log.info("id="+id);
            if(id == null)
            {
                Integer pId = categoryForm.getParentId();//forward after add            
                id = pId;
            }
            if(id == null)
            {
                Collection list = null;            
                list = listAll();
                request.setAttribute("sfclist",list);
            }
            else
            {
                SharedFileCategory sfc = get(id);
                request.setAttribute("sfc",sfc);
                log.info("list size="+sfc.getMrIaskSharedFileCategories().size());
            }
        }
        if(af != null)
            return af;
        else
            return mapping.findForward(action);
    }
    */
    public SharedFileCategory get(Integer id) throws QaException
    {
        Transaction tx = null;
        try
        {
            SharedFileCategoryDAO sharedFileCategoryDAO = new SharedFileCategoryDAO();
            SharedFileCategory sharedFileCategory = sharedFileCategoryDAO.findById(id);
            return sharedFileCategory;
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();  
        }
    }
	
    public Collection listAll() throws QaException
    {
        Transaction tx = null;
        Collection list = null;
        try
        {
            tx = HibernateSessionFactory.getSession().beginTransaction();
            SharedFileCategoryDAO sharedFileCategoryDAO = new SharedFileCategoryDAO();
            list = sharedFileCategoryDAO.findAll();
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();  
        }
        return list;
    }
	
    public void add(SharedFileCategoryForm categoryForm) throws QaException
    {
        Transaction tx = null;
        try 
        {
            SharedFileCategoryDAO sharedFileCategoryDAO = new SharedFileCategoryDAO();
            tx = HibernateSessionFactory.getSession().beginTransaction();
            Integer pId = categoryForm.getParentId();
            if(pId != null && pId.intValue() > 0)
            {
                SharedFileCategory parent = null;            
                parent = sharedFileCategoryDAO.findById(pId);
                SharedFileCategory sharedFileCategory = new SharedFileCategory();
                sharedFileCategory.setName(categoryForm.getName());
                sharedFileCategory.setLevel(parent.getLevel()+1);
                sharedFileCategory.setPriority(categoryForm.getPriority());
                sharedFileCategory.setMrIaskSharedFileCategory(parent);
                sharedFileCategory.setFileCount(0);
                sharedFileCategoryDAO.save(sharedFileCategory);
            }
            else
            {
                SharedFileCategory sharedFileCategory = new SharedFileCategory();
                sharedFileCategory.setMrIaskSharedFileCategory(null);
                sharedFileCategory.setName(categoryForm.getName());
                sharedFileCategory.setLevel(1);
                sharedFileCategory.setPriority(categoryForm.getPriority());
                sharedFileCategory.setFileCount(0);
                sharedFileCategoryDAO.save(sharedFileCategory);
            }
            tx.commit();
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();  
        }
    }
	
	
    public void modify(SharedFileCategoryForm categoryForm) throws QaException
    {
        Transaction tx = null;
        try
        {
            SharedFileCategoryDAO sharedFileCategoryDAO = new SharedFileCategoryDAO();
            Integer id = categoryForm.getId();
            //log.info("id="+id);
            tx = HibernateSessionFactory.getSession().beginTransaction();
            SharedFileCategory sharedFileCategory = sharedFileCategoryDAO.findById(id);
            //log.info("name="+categoryForm.getName());
            sharedFileCategory.setName(categoryForm.getName());
            //log.info("priority="+categoryForm.getPriority());
            sharedFileCategory.setPriority(categoryForm.getPriority());
            sharedFileCategoryDAO.update(sharedFileCategory);
            tx.commit();
            //log.info("comment");
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();  
        }
    }
	
    public void delete(Integer id) throws QaException
    {
        Transaction tx = null;
        try
        {
            SharedFileCategoryDAO sharedFileCategoryDAO = new SharedFileCategoryDAO();        
            tx = HibernateSessionFactory.getSession().beginTransaction();
            SharedFileCategory sharedFileCategory = sharedFileCategoryDAO.findById(id);
            sharedFileCategoryDAO.delete(sharedFileCategory);
            tx.commit();
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();  
        }
    }
    
    /*
     *Below are private methods
     */
    private List list(int page,int pageSize,Integer catId) throws QaException
    {
        Transaction tx = null;
        List list = new ArrayList();        
        try
        {
            SharedFileDAO sharedFileDAO = new SharedFileDAO();
            sharedFileDAO.setPage(page, pageSize);
            tx = HibernateSessionFactory.getSession().beginTransaction();
            if(catId != null)
            {
                list = sharedFileDAO.findSharedFilesUnderACategoryForAdmin(catId);
            }
            tx.commit();
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();
        }
        return list;        
    }
        
    private int countSharedFile(Integer catId) throws QaException
    {    
        Transaction tx = null;
        int count = 0;
        try
        {
            SharedFileDAO sharedFileDAO = new SharedFileDAO();
            tx = HibernateSessionFactory.getSession().beginTransaction();
            if(catId != null)
            {
                count = sharedFileDAO.countSharedFilesUnderACategoryForAdmin(catId);
            }
            tx.commit();
        }
        catch(Exception e)
        {
            if(tx != null)tx.rollback();
            throw new QaException(e);
        }
        finally
        {
            HibernateSessionFactory.closeSession();
        }
        return count;
    }    
    
}
